﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FieldTools.Util.Helper
{
    /// <summary>
    /// ADB帮助类，借鉴https://gitee.com/ninghong001/AndroidADBTool项目，感谢开源，节约了很多时间。使用前，请确保运行目录中包含了adb相关工具包或者指定AdbPath与AaptPath
    /// </summary>
    public class ADBHelper
    {
        /// <summary>
        /// adb路径
        /// </summary>
        public static string AdbPath = @"\Tools\adb\adb.exe";
        /// <summary>
        /// aapt目录
        /// </summary>
        public static string AaptPath = @"\Tools\adb\aapt.exe";
        /// <summary>
        /// 获取设备列表
        /// </summary>
        /// <returns></returns>
        public static List<string> GetDevices()
        {
            string output = RunCmd("devices");
            string str = "List of devices attached";
            output = output[output.IndexOf(str)..];
            string[] sp = { "\r\n" };
            List<string> list = output.Split(sp, StringSplitOptions.RemoveEmptyEntries).ToList().Select(x => x.Split("\t").First()).ToList();
            //List<string> list = new();
            //var tempList = output.Split(sp, StringSplitOptions.RemoveEmptyEntries).ToList();
            //tempList.ForEach(x =>
            //{
            //    x.Split("\t");
            //});
            list.Remove(str);
            return list;
        }

        /// <summary>
        /// 连接（网络）
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        /// <returns></returns>
        public static string Connect(string ip, string port)
        {
            return RunCmd($"connect {ip}:{port}");
        }

        /// <summary>
        /// 连接
        /// </summary>
        /// <param name="host"></param>
        /// <returns></returns>
        public static string Connect(string host)
        {
            return RunCmd($"connect {host}");
        }

        /// <summary>
        /// 断开设备连接
        /// </summary>
        /// <param name="host"></param>
        public static string DisConnect(string host)
        {
            return RunCmd($"disconnect {host}");
        }

        /// <summary>
        /// 关闭cmd服务
        /// </summary>
        /// <returns></returns>
        public static string KillAdb()
        {
            return RunCmd("kill-server");
        }
        /// <summary>
        /// 安装apk软件
        /// </summary>
        /// <param name="host"></param>
        /// <param name="apkfile"></param>
        /// <returns></returns>
        public static string InstallApk(string host, string apkfile)
        {
            string aaptPath = Path.GetFullPath(AppDomain.CurrentDomain.BaseDirectory) + AaptPath;
            string fileoutput = CMDHelper.RunCmd(aaptPath, $@"dump badging ""{apkfile}""");
            string str_1 = "package: name=";
            var temp1 = fileoutput.Substring(fileoutput.IndexOf(str_1) + str_1.Length);
            string temp2 = temp1[..temp1.IndexOf("versionCode=")].TrimEnd();
            string package = temp2.Replace("'", "");
            string str = "launchable-activity: name=";
            var str1 = fileoutput.Substring(fileoutput.IndexOf(str) + str.Length);
            var str2 = str1[..str1.IndexOf("label=")].TrimEnd().Replace("'", "");
            string activity = str2.Replace(package, "");
            string output = RunCmd($@"-s {host} install -r ""{apkfile}""");
            output += RunCmd($@"-s {host} shell am start {package}/{activity}");
            return output;
        }
        /// <summary>
        /// 安装apk软件到系统调试目录
        /// </summary>
        /// <param name="host"></param>
        /// <param name="apkfile"></param>
        /// <returns></returns>
        public static string InstallApkToSystem(string host, string apkfile)
        {
            string output = RunCmd($"-s {host} root");
            output += RunCmd($"-s {host} remount");
            output += RunCmd($@"-s {host} push ""{apkfile}"" /system/app");
            return output;
        }

        /// <summary>
        /// 获取包名
        /// </summary>
        /// <param name="host"></param>
        /// <returns></returns>
        public static List<string> GetThirdPackage(string host)
        {
            List<string> list = new();
            string output = RunCmd($"-s {host} shell pm list packages -3");
            
            string str = "package:";
            if (output.IndexOf(str) != -1)
            {
                output = output[output.IndexOf(str)..];
                string[] sp = { str };
                list = output.Split(sp, StringSplitOptions.RemoveEmptyEntries).ToList();
                list.Remove(str);
            }
            return list;
        }
        /// <summary>
        /// 卸载程序包
        /// </summary>
        /// <param name="host"></param>
        /// <param name="packagename"></param>
        /// <param name="keepdata"></param>
        /// <returns></returns>
        public static string UnInstallPackage(string host, string packagename, bool keepdata = false)
        {
            string k = keepdata ? "-k" : "";
            return RunCmd($"-s {host} uninstall {k} {packagename}");
        }

        /// <summary>
        /// 开启无线调试，默认5555端口
        /// </summary>
        /// <param name="host"></param>
        /// <param name="port"></param>
        /// <returns></returns>
        public static string OpenAdbd(string host, string port = "5555")
        {
            string output = RunCmd($"-s {host} root");
            output += RunCmd($"-s {host} remount");
            output += RunCmd($@"-s {host} pull /system/build.prop ""{AppDomain.CurrentDomain.BaseDirectory}\""");
            string file = AppDomain.CurrentDomain.BaseDirectory + "\\build.prop";
            var lines = File.ReadLines(file, Encoding.UTF8).ToList();
            if (!lines.Exists(x => x.Contains("service.adb.tcp.port")))
            {
                lines.Add("service.adb.tcp.port=5555");
            }
            File.WriteAllLines(file, lines, Encoding.UTF8);
            output += RunCmd($@"-s {host} push ""{file}"" /system");
            output += RunCmd($@"-s {host} tcpip {port}");
            output += RunCmd($"-s {host} shell am restart");
            return output;
        }

        /// <summary>
        /// 关闭应用
        /// </summary>
        /// <param name="host"></param>
        /// <param name="pack"></param>
        /// <returns></returns>
        public static string CloseApp(string host, string pack)
        {
            return RunCmd($"-s {host} shell am force-stop {pack}");
        }
        /// <summary>
        /// 执行abd指令
        /// </summary>
        /// <param name="host"></param>
        /// <param name="order"></param>
        /// <returns></returns>
        public static string ExecuteAbdbOrder(string host, string order)
        {
            return RunCmd($"-s {host} {order}");
        }

        /// <summary>
        /// 重启系统
        /// </summary>
        /// <param name="host"></param>
        /// <returns></returns>
        public static string RestartSystem(string host)
        {
            return RunCmd($"-s {host} shell am restart");
        }

        /// <summary>
        /// adb运行cmd命令，请保证adb.exe及其组件位于指定目录下
        /// </summary>
        /// <param name="cmdStr"></param>
        /// <param name="adbPath"></param>
        /// <returns></returns>
        public static string RunCmd(string cmdStr)
        {
            string adbPath = Path.GetFullPath(AppDomain.CurrentDomain.BaseDirectory) + AdbPath;
            string output = CMDHelper.RunCmd(adbPath, cmdStr);
            Console.WriteLine(output);
            return output + Environment.NewLine;
        }
    }
}
